const Controller = require('egg').Controller

class TestController extends Controller {
    // 获取试题列表
    async getTests() {
        try {
            const { app, ctx } = this;
            const { Op } = app.Sequelize;
            const { searchForm, page, limit } = ctx.request.body;
            let conditions = {}
            if(!searchForm) {
            } else {
              if(!!searchForm.title) {
                conditions.title = {[Op.startsWith]: searchForm.title};
              }
            }
            const pageOffset = ctx.helper.toInt((page - 1) * limit);
            const pageLimit = ctx.helper.toInt(limit);
            const tests = await ctx.service.test.findList({
              where: conditions,
              limit: pageLimit,
              offset: pageOffset
            })
            ctx.body = {
                code: '0',
                desc: '获取试题列表成功',
                tests: tests.rows,
                count: tests.count
            }
        } catch(error) {
            const { ctx } = this
            ctx.body = {
              code: '-1',
              desc: '获取试题列表失败',
              err: error
            }
        }
    }
    
    // 获取考生试题
    async getUserTests() {
      try {
        const { ctx } = this
        const { id } = ctx.request.body
        const u = await ctx.model.User.findByPk(id)
        const ts = await u.getTests()

        // 获取考生考试记录
        const rs = await ctx.model.TestUser.findAll({
          attributes: { exclude: ['answers'] },
          where: {
            user_id: id
          }
        })

        ctx.body = {
          code: '0',
          content: ts,
          records: rs,
          desc: '考生试题获取成功'
        }
      } catch(error) {
        const { ctx } = this
        
        ctx.body = {
            code: '-1',
            desc: '试题获取失败',
            err: error
        }
      }
    }

    // 获取特指考试数据（包括考生及答案）
    async getTestById() {
      try {
        const { ctx } = this
        const { id } = ctx.request.body
        const t = await ctx.model.Test.findByPk(id)
        const ts = await t.getUsers()
        
        ctx.body = {
          code: '0',
          detail: t,
          testers: ts,
          desc: '试题获取成功'
        }
      } catch(error) {
        const { ctx } = this
        
        ctx.body = {
          code: '-1',
          desc: '试题获取失败',
          err: error
        }
      }
    }

    // 考生获取特指试卷（不包括考生及答案）
    async getTestByUser() {
      try {
        const { ctx } = this
        const { id } = ctx.request.body
        // 获取考试数据（去掉答案）
        const t = await ctx.model.Test.findByPk(id)
        t.questions = JSON.parse(t.questions).map(i => {
          return {
            id: i.id,
            typeId: i.typeId,
            title: i.title,
            score: i.score,
            answer: [],
            content: i.content
          }
        })
        ctx.body = {
          code: '0',
          detail: t,
          desc: '试题获取成功'
        }
      } catch(error) {
        const { ctx } = this
        ctx.body = {
          code: '-1',
          desc: '试题获取失败',
          err: error
        }
      }
    }

    async createTest() {
      try {
        const { ctx } = this
        const { title, deadline, questions, userId } = ctx.request.body
        const testItem = await ctx.model.Test.create({
          title,
          deadline,
          questions
        })
        //userId允许多个，为数组
        await testItem.addUsers(userId)
        
        ctx.body = {
          code: '0',
          desc: '试题创建成功'
        }
      } catch(error) {
        const { ctx } = this

        ctx.body = {
          code: '-1',
          desc: '试题创建失败'
        }
      }
    }

    async editTest() {
      try {
        const { ctx } = this
        const { id, title, deadline, questions, userId } = ctx.request.body
        await ctx.model.Test.update({
          title,
          deadline,
          questions
        }, {
          where: {
            id
          }
        })
        const testItem = await ctx.model.Test.findByPk(id)
        //userId允许多个，为数组
        await testItem.setUsers(userId)

        ctx.body = {
          code: '0',
          desc: '试题修改成功'
        }
      } catch(error) {
        const { ctx } = this

        ctx.body = {
          code: '-1',
          desc: '试题修改失败'
        }
      }
    }

    async deleteTest() {
      try {
        const { ctx } = this
        const { id } = ctx.request.body
        await ctx.model.Test.destroy({
          where: {
            id
          }
        })
        ctx.body = {
          code: '0',
          desc: '试题删除成功'
        }
      } catch(error) {
        const { ctx } = this

        ctx.body = {
          code: '-1',
          desc: '试题删除失败'
        }
      }
    }

    async batchDeleteTests() {
      try {
        const { ctx } = this
        const { ids } = ctx.request.body
        await user.destroy({
          where: {
            id: {
              [Op.in]: ids
            }
          }
        })
        ctx.body = {
          code: '0',
          desc: '批量删除成功'
        }
      } catch(error) {
        const { ctx } = this

        ctx.body = {
          code: '-1',
          desc: '批量删除失败'
        }
      }
    }

    // 计算分数（仅包括选择和判断）
    async calculateScore() {
      try {
        const { ctx } = this
        const { id, userid, answers } = ctx.request.body
        // 考生答案，格式为[{ id: id, typeId: typeId, score: score, answer: answer }]
        // 找到测试题
        const t = await ctx.model.Test.findByPk(id)
        // 重新赋值问题内容
        t.questions = JSON.parse(t.questions).map(i => {
          return {
            id: i.id,
            typeId: i.typeId,
            score: i.score,
            answer: i.answer
          }
        })
        // 分类计算分数
        // 多选题错一个不得分，简答和填空需人工给分
        let total = 0
        answers.forEach(a => {
          // 找匹配题目id
          let q = t.questions.find(i => { return i.id == a.id })
          if(JSON.stringify(q.answer) == JSON.stringify(a.answer)) {
              total += Number(q.score)
          }
        })

        // 把考生答案和分数存入usertest表中
        await ctx.model.TestUser.update({
          score: total,
          answers: JSON.stringify(answers)
        }, {
          where: {
            user_id: userid,
            test_id: id
          }
        })

        ctx.body = {
          code: '0',
          score: total
        }
      } catch(error) {
        const { ctx } = this

        ctx.body = {
          code: '-1',
          desc: '分数计算失败，请重试~',
          err: error
        }
      }
    }
}

module.exports = TestController;